package com.ali.netty;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoop;
import io.netty.handler.timeout.IdleStateEvent;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

/**
 * 自定义服务端处理器
 */
public class MyServerHandler extends ChannelInboundHandlerAdapter {
    /**
     * 处理器添加
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        System.out.println("handlerAdded方法执行");
    }

    /**
     * 通道注册
     */
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) {
        System.out.println("channelRegistered方法执行");
    }

    /**
     * 通道激活
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        System.out.println("channelActive方法执行");
    }

    /**
     * 通道读取
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("channelRead方法执行");
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("接收消息：" + byteBuf.toString(StandardCharsets.UTF_8));
        System.out.println("客户端地址：" + ctx.channel().remoteAddress());
        System.out.println("线程名：" + Thread.currentThread().getName());

        //获取事件循环
        EventLoop eventLoop = ctx.channel().eventLoop();
        //异步普通任务
        eventLoop.execute(() -> {
            try {
                Thread.sleep(5000);
                System.out.println("异步普通任务");
                System.out.println("线程名：" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        //异步定时任务
        eventLoop.schedule(() -> {
            System.out.println("异步定时任务");
            System.out.println("线程名：" + Thread.currentThread().getName());
        }, 5, TimeUnit.SECONDS);
    }

    /**
     * 通道读取完成
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        System.out.println("channelReadComplete方法执行");
    }

    /**
     * 通道非激活
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        System.out.println("channelInactive方法执行");
    }

    /**
     * 通道取消注册
     */
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) {
        System.out.println("channelUnregistered方法执行");
    }

    /**
     * 处理器移除
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        System.out.println("handlerRemoved方法执行");
    }

    /**
     * 异常处理
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        System.out.println("exceptionCaught方法执行");
        //关闭客户端连接
        ctx.close();
    }

    /**
     * 事件触发
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
        System.out.println("userEventTriggered方法执行");
        Channel channel = ctx.channel();
        //判断是否是空闲事件
        if (evt instanceof IdleStateEvent idleStateEvent) {
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    System.out.println(channel.remoteAddress() + "：读空闲");
                    break;
                case WRITER_IDLE:
                    System.out.println(channel.remoteAddress() + "：写空闲");
                    break;
                case ALL_IDLE:
                    System.out.println(channel.remoteAddress() + "：读写空闲");
                    break;
            }
        }
    }
}
